package com.zhuoyue.common.utils;

import org.apache.commons.lang3.StringUtils;

/**
 * 进制转化工具
 *
 * @author Administrator
 */
public class DataTypeUtil {
    private static final int DEFAULT_COVERING_POSITION_LENGTH = 4;

    /**
     * 16进制转化为2进制
     *
     * @param str
     * @return 2进制数据
     */
    public static String hexToBinary(String str) {
        return hexToBinary(str, true);
    }

    /**
     * 16进制转化为2进制 缺位补0
     *
     * @param str
     * @param isCoveringPosition
     * @return
     */
    public static String hexToBinary(String str, boolean isCoveringPosition) {
        StringBuilder hex = new StringBuilder();
        int decimal = hexToDecimal(str).intValue();
        String binary = decimalToBinary(decimal);
        hex.append(binary);
        if (isCoveringPosition) {
            int len = binary.length();
            if (len < DEFAULT_COVERING_POSITION_LENGTH) {
                for (int i = 0; i < DEFAULT_COVERING_POSITION_LENGTH - len; i++) {
                    hex.insert(0, "0");
                }
            }
        }
        return hex.toString();
    }

    /**
     * //16进制转化为10进制
     *
     * @param str
     * @return
     */
    public static Integer hexToDecimal(String str) {
        try {
            int dec = Integer.valueOf(str, 16).intValue();
            return Integer.valueOf(dec);
        } catch (Exception localException) {
        }
        return 0;
    }

    /**
     * 16进制转化为8进制
     *
     * @param str
     * @return
     */
    public static String hexToOctal(String str) {
        int dec = hexToDecimal(str).intValue();
        return decimalToOctal(dec);
    }

    /**
     * 10进制转化为2进制
     *
     * @param dec
     * @return
     */
    public static String decimalToBinary(int dec) {
        return Integer.toBinaryString(dec);
    }

    /**
     * 10进制转化为8进制
     *
     * @param dec
     * @return
     */
    public static String decimalToOctal(int dec) {
        return Integer.toOctalString(dec);
    }

    /**
     * 10->16
     *
     * @param dec
     * @return
     */
    public static String decimalToHex(int dec) {
        String s = Integer.toHexString(dec);
        return s.length() == 1 ? "0" + s : s;
    }

    /**
     * 2-->8
     *
     * @param binary
     * @return
     */
    public static String binaryToOctal(String binary) {
        int dec = binaryToDecimal(binary);
        return decimalToOctal(dec);
    }

    /**
     * 2-->16
     *
     * @param binary
     * @return
     */
    public static String binaryToHex(String binary) {
        int dec = binaryToDecimal(binary);
        return decimalToHex(dec);
    }

    /**
     * 2-->10
     *
     * @param binary
     * @return
     */
    public static int binaryToDecimal(String binary) {
        return Integer.valueOf(binary, 2).intValue();
    }

    /**
     * 8-->2
     *
     * @param octal
     * @return
     */
    public static String octalToBinary(String octal) {
        int dec = octalToDecimal(octal);
        return Integer.toBinaryString(dec);
    }

    /**
     * 8-->10
     *
     * @param octal
     * @return
     */
    public static int octalToDecimal(String octal) {
        return Integer.valueOf(octal, 8).intValue();
    }

    /**
     * 8==>16
     *
     * @param octal
     * @return
     */
    public static String octalToHex(String octal) {
        int dec = octalToDecimal(octal);
        return decimalToHex(dec);
    }

    /**
     * bytes-->16
     *
     * @param b
     * @param vLen
     * @return
     */
    public static String bytes2HexString(byte[] b, int vLen) {
        String ret = "";
        for (int i = 0; i < vLen; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            ret += hex;
        }
        return ret;
    }

    /**
     * 16-->bytes
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return null;
        }

        hexString = hexString.toUpperCase();

        int length = hexString.length() / 2;

        char[] hexChars = hexString.toCharArray();

        byte[] d = new byte[length];

        for (int i = 0; i < length; i++) {
            int pos = i * 2;

            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[(pos + 1)]));
        }

        return d;
    }

    /**
     * 16-->byte
     *
     * @param hexString
     * @return
     */
    public static byte hexStringToByte(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return 0x00;
        }

        hexString = hexString.toUpperCase();

        int length = hexString.length() / 2;

        char[] hexChars = hexString.toCharArray();

        byte[] d = new byte[length];

        for (int i = 0; i < length; i++) {
            int pos = i * 2;

            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[(pos + 1)]));
        }

        return d[d.length - 1];
    }

    /**
     * char->byte
     *
     * @param c
     * @return
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 加法和校验值
     *
     * @param checkStr
     * @return
     */
    public static String getAddCheck(String checkStr) {
        byte[] data = DataTypeUtil.hexStringToBytes(checkStr);
        byte addSum = 0;
        for (int i = 0; i < data.length; i++) {
            addSum += data[i];
        }
        return String.format("%02x", addSum & 0xff);
    }

    /**
     * 异或和校验
     *
     * @param checkStr
     * @return
     */
    public static String getAddCheckByXor(String checkStr) {
        byte[] data = DataTypeUtil.hexStringToBytes(checkStr);
        byte[] temp = new byte[1];
        temp[0] = data[0];
        for (int i = 1; i < data.length; i++) {
            temp[0] ^= data[i];
        }
        return DataTypeUtil.bytes2HexString(temp, temp.length);
    }

    /**
     * SCII转换为字符串
     *
     * @param s
     * @return
     */
    public static String asciiToString(String s) {
        byte[] baKeyword = new byte[s.length() / 2];
        for (int i = 0; i < baKeyword.length; i++) {
            try {
                baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            s = new String(baKeyword, "ASCII");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return s;
    }

    /**
     * 字符串(16进制)转换为ASCII码
     *
     * @param data
     * @return
     */
    public static String stringToAscii(String data) {
        StringBuilder result = new StringBuilder("");
        char[] chars = data.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            int temp = chars[i];
            result.append(setBytesLen(decimalToHex(temp), 1, false));
        }
        return result.toString();
    }


    /**
     * 获取有符号的单字节数据:信号强度为0，信号强度总为负值，最高位代表符号位，1为负，数值越大信号越好，理论范围0~-127（上电初始上报为0）
     *
     * @param data
     * @return
     */
    public static String getSymbolDataByOneByte(String data) {
        String temp = hexToBinary(data, true);
        String t1 = temp.substring(0, 1);
        String t2 = "0" + temp.substring(1, temp.length());
        return "1".equals(t1) ? "-" + (128 - binaryToDecimal(t2)) : "" + binaryToDecimal(t2);
    }

    /**
     * 指定字节长度补全
     */
    public static String setBytesLen(String s, int bytesNum, boolean zeroAtAfter) {
        int length = bytesNum * 2;
        if ("".equals(s)) {
            return "";
        }

        int len = s.length();
        if (len == length) {
            return s;
        }
        if (len < length) {
            int temp = length - len;
            for (int i = 0; i < temp; i++) {
                s = zeroAtAfter ? s + "0" : "0" + s;
            }
        } else if (len > length) {
            s = s.substring(len - length, len);
        }
        return s;
    }

    /**
     * 子字符串在父字符串中出现的次数
     */
    public static int stringSub(String str, String substr) {
        int index = 0;
        int count = 0;
        int fromindex = 0;
        while ((index = str.indexOf(substr, fromindex)) != -1) {
            fromindex = index + substr.length();
            count++;
        }
        return count;
    }


}
